import os
import stat
import uuid
import datetime
from typing import List

from PySide2.QtWidgets import *
from PySide2.QtCore import QFile, QStringListModel, Qt, QObject, QRect
from PySide2.QtUiTools import QUiLoader

import CodeLayaGenerator
import Logger
import SvnTool
import Util
from ExcelData import EData, SaveType

import ICodeGenerator
import CodeJavaGenerator

from UiCoder import Ui_CoderDialog

class CoderDialog(QWidget, Ui_CoderDialog):
    edata: EData
    logger: Logger

    def __init__(self):
        super(CoderDialog, self).__init__()
        self.edata = EData()
        self.logger = Logger.Logger()

        self.ui = Ui_CoderDialog()
        self.ui.setupUi(self)

        # 绑定事件
        self.ui.btnClose.clicked.connect(self.onBthCloseClick)

        self.ui.btnGenJava.clicked.connect(self.onBthGenJavaClick)
        self.ui.btnUpdateJava.clicked.connect(self.onBthUpdateJavaClick)
        self.ui.btnGenLaya.clicked.connect(self.onBthGenLayaClick)
        self.ui.btnUpdateLaya.clicked.connect(self.onBthUpdateLayaClick)

        self.ui.btnSelectDirJavaFile.clicked.connect(self.onSelectDirJavaFileClick)
        self.ui.btnSelectDirJavaFileCopy.clicked.connect(self.onSelectDirJavaFileCopyClick)
        self.ui.btnSelectDirLayaFile.clicked.connect(self.onSelectDirLayaFileClick)
        self.ui.btnSelectDirLayaFileCopy.clicked.connect(self.onSelectDirLayaFileCopyClick)

        self.ui.btnOpenDirJavaFile.clicked.connect(self.onBtnOpenDirJavaFileClick)
        self.ui.btnOpenDirJavaFileCopy.clicked.connect(self.onBtnOpenDirJavaFileCopyClick)
        self.ui.btnOpenDirLayaFile.clicked.connect(self.onBtnOpenDirLayaFileClick)
        self.ui.btnOpenDirLayaFileCopy.clicked.connect(self.onBtnOpenDirLayaFileCopyClick)

    def show(self):
        print("打开生成UI")
        super(CoderDialog, self).show()
        self.loadFromData()

        self.resetFormPosition()

    def closeEvent(self, event):
        print("点击X关闭窗口")
        self.saveFromData()
        self.edata.save(SaveType.Setting)


    def onBthCloseClick(self):
        print("点击关闭按钮关闭窗口")
        self.saveFromData()
        self.edata.save(SaveType.Setting)
        self.close()

    def loadFromData(self):
        self.ui.txtDirJavaFile.setText(self.edata.setting.genDirJavaFile)
        self.ui.txtDirLayaFile.setText(self.edata.setting.genDirLayaFile)
        self.ui.txtDirJavaFileCopy.setText(self.edata.setting.genDirJavaFileCopy)
        self.ui.txtDirLayaFileCopy.setText(self.edata.setting.genDirLayaFileCopy)

        self.ui.chkUpdateCopy.setChecked(self.edata.setting.chkUpdateCopy)
        self.ui.chkGenSvn.setChecked(self.edata.setting.chkGenSvn)
        self.ui.chkGenCopy.setChecked(self.edata.setting.chkGenCopy)
        self.ui.chkDelOld.setChecked(self.edata.setting.chkDelOld)

        self.ui.chkAutoOpenFolderGenCode.setChecked(self.edata.setting.chkAutoOpenFolderGenCode)

        self.ui.chkClearDirGen.setChecked(self.edata.setting.chkClearDirGen)
        self.ui.chkClearDirCopy.setChecked(self.edata.setting.chkClearDirCopy)

    def saveFromData(self):
        self.edata.setting.genDirJavaFile = self.ui.txtDirJavaFile.text()
        self.edata.setting.genDirLayaFile = self.ui.txtDirLayaFile.text()
        self.edata.setting.genDirJavaFileCopy = self.ui.txtDirJavaFileCopy.text()
        self.edata.setting.genDirLayaFileCopy = self.ui.txtDirLayaFileCopy.text()

        self.edata.setting.chkUpdateCopy = self.ui.chkUpdateCopy.isChecked()
        self.edata.setting.chkGenSvn = self.ui.chkGenSvn.isChecked()
        self.edata.setting.chkGenCopy = self.ui.chkGenCopy.isChecked()
        self.edata.setting.chkDelOld = self.ui.chkDelOld.isChecked()

        self.edata.setting.chkAutoOpenFolderGenCode = self.ui.chkAutoOpenFolderGenCode.isChecked()

        self.edata.setting.chkClearDirGen = self.ui.chkClearDirGen.isChecked()
        self.edata.setting.chkClearDirCopy = self.ui.chkClearDirCopy.isChecked()

    isFirstShow:bool = True
    def resetFormPosition(self):
        # 调整窗口位置，不阻挡logs
        # Util.setToTop(self)
        mainRect: QRect = Util.mainForm.geometry()
        if self.isFirstShow:
            # pyside2奇怪的bug，第一次打开坐标不准，第二次才准，所以只能用标记处理第一次打开的坐标
            self.isFirstShow = False
            x = Util.mainForm.x() + ((Util.mainForm.width() - self.width()) / 2)
            y = Util.mainForm.y() + 50
        else:
            mainRect: QRect = Util.mainForm.geometry()
            x = mainRect.x() + ((mainRect.width() - self.width()) / 2)
            y = mainRect.y() + 50

        self.move(x, y)

    def onSelectDirJavaFileClick(self):
        path = QFileDialog.getExistingDirectory(self, "选择Java生成Vo代码目录", "")
        if not path is None:
            path = path.replace("/", "\\").replace(self.edata.currentPath, "")
            if not path.endswith("\\"):
                path += "\\"
            self.ui.txtDirJavaFile.setText(path)

    def onSelectDirJavaFileCopyClick(self):
        path = QFileDialog.getExistingDirectory(self, "选择JavaVo生成后自动拷贝目录", "")
        if not path is None:
            path = path.replace("/", "\\").replace(self.edata.currentPath, "")
            if not path.endswith("\\"):
                path += "\\"
            self.ui.txtDirJavaFileCopy.setText(path)

    def onSelectDirLayaFileClick(self):
        path = QFileDialog.getExistingDirectory(self, "选择Laya生成Vo代码目录", "")
        if not path is None:
            path = path.replace("/", "\\").replace(self.edata.currentPath, "")
            if not path.endswith("\\"):
                path += "\\"
            self.ui.txtDirLayaFile.setText(path)

    def onSelectDirLayaFileCopyClick(self):
        path = QFileDialog.getExistingDirectory(self, "选择LayaVo生成后自动拷贝目录", "")
        if not path is None:
            path = path.replace("/", "\\").replace(self.edata.currentPath, "")
            if not path.endswith("\\"):
                path += "\\"
            self.ui.txtDirLayaFileCopy.setText(path)

    def onBtnOpenDirJavaFileClick(self):
        path = self.ui.txtDirJavaFile.text()
        Util.openFilePath(path)

    def onBtnOpenDirJavaFileCopyClick(self):
        path = self.ui.txtDirJavaFileCopy.text()
        Util.openFilePath(path)

    def onBtnOpenDirLayaFileClick(self):
        path = self.ui.txtDirLayaFile.text()
        Util.openFilePath(path)

    def onBtnOpenDirLayaFileCopyClick(self):
        path = self.ui.txtDirLayaFileCopy.text()
        Util.openFilePath(path)

    def getCodePath(self, settingVoPath: str):
        """获取代码生成真实路径。获取失败会返回None"""
        if not os.path.isabs(settingVoPath):  # 检查是否绝对路径
            settingVoPath = self.edata.currentPath + settingVoPath  # 非绝对路径则加上执行目录
            settingVoPath = settingVoPath.replace("\\\\", "\\")  # 去掉双重\\的路径
        if not os.path.exists(settingVoPath) or not os.path.isdir(settingVoPath):
            self.logger.logWarning("检测目录不存在，自动创建：" + settingVoPath)
            Util.tryCreateDirectory(settingVoPath)
        return settingVoPath

    def clearGenFolder(self, genVoBasePath:str):
        """
        清理生成目录
        :param genVoBasePath:  生成对应代码VO的地址
        :return:
        """
        # 先删除旧文件目录
        self.logger.logNotice("删除临时文件夹：" + genVoBasePath)
        Util.deleteDirectoryFiles(genVoBasePath, True, "*.*")

    def checkOutSvn(self, genVoBasePath:str, tempFolder: str, svnPath:str):
        """
        检出svn
        :param genVoBasePath: 生成对应代码VO的地址
        :param tempFolder: 动态创建临时目录
        :param svnPath: svn上对应的目录
        :return:
        """
        # Java
        self.logger.logSpace()  # 空行
        self.logger.logNotice("开始检出'"+ svnPath + "'SVN...")
        # SVN尝试创建目录
        svnUrl: str = self.edata.setting.svnUrl + svnPath
        SvnTool.svnMkdir(self.logger,
                         svnUrl,
                         self.edata.setting.svnUser,
                         self.edata.setting.svnPwd)
        # SVN检出文件
        svnJavaTempDir = SvnTool.checkoutSvnDir(self.logger,
                                                genVoBasePath + tempFolder,
                                                svnUrl,
                                                self.edata.setting.svnUser,
                                                self.edata.setting.svnPwd)
        self.logger.logAllDone("检出'"+ svnPath + "'SVN完毕...")
        return True

    def commitSvn(self, genCodePath:str, svnPath:str, extFileName: str):
        """
        提交svn
        :param genCodePath: 代码生成目录，需要提交svn的目录
        :return:
        """
        self.logger.logSpace()  # 空行
        self.logger.logNotice("开始提交'"+ svnPath + "'SVN...")
        if not genCodePath.endswith("\\"):
            genCodePath += "\\"
        files: List[str] = []
        files.append(genCodePath +
                     self.edata.setting.genLibConstantClass +
                     extFileName)
        files.append(genCodePath +
                     self.edata.setting.genLibEasyAccessClass +
                     extFileName)
        for excel in self.edata.excelDatas.selectedDatas.values():
            for table in excel.tables.values():
                fileFullName: str = genCodePath + table.getClassname() + extFileName
                files.append(fileFullName)
        self.logger.logNotice("[SVN][Commit] 开始提交生成的'"+ svnPath + "' Vo代码...")
        SvnTool.commitSVNFiles(self.logger,
                               genCodePath,
                               self.edata.setting.svnUrl + svnPath,
                               files,
                               self.edata.setting.svnUser,
                               self.edata.setting.svnPwd)
        self.logger.logNotice("[SVN][Commit] 提交生成的'"+ svnPath + "' Vo代码结束")
        self.logger.logAllDone("提交SVN完毕...")

    def onBthUpdateJavaClick(self):
        # 屏蔽按钮可按，防止重复点击
        self.setRunningStatus(True)
        exportTime = datetime.datetime.now()
        tempFolder:str = "svn_" + exportTime.strftime("%Y-%m-%d_%H-%M-%S")
        voBasePath: str = self.getGenJavaVoBasePath()
        voGenPath: str = voBasePath + tempFolder
        if voBasePath is None:
            self.logger.logError("找不到Java生成代码目录地址！")
            return False
        # 清理临时目录之前的文件
        if self.ui.chkClearDirGen.isChecked():
            self.clearGenFolder(voBasePath)
        # 检出SVN
        if not self.checkOutSvn(voBasePath,
                                tempFolder,
                                self.edata.setting.svnDirJava):
            return
        # 拷贝代码到目标目录
        if self.ui.chkUpdateCopy.isChecked():
            targetPath:str = self.ui.txtDirJavaFileCopy.text()
            if not os.path.isabs(targetPath):
                targetPath = self.edata.currentPath + targetPath
            if not os.path.isdir(targetPath):
                self.logger.logError("自动拷贝代码目标路径有误：" + targetPath)
            else:
                if self.ui.chkClearDirCopy.isChecked():
                    Util.deleteDirectoryFiles(targetPath, False, CodeJavaGenerator.CodeJavaGenerator.CODE_FILE_EXT_NAME)
                Util.copyDirectoryFiles(voGenPath, targetPath)
                if self.ui.chkAutoOpenFolderGenCode.isChecked():
                    Util.openFilePath(targetPath)

        # 恢复按钮可按
        self.setRunningStatus(False)
        # 打开生成目录
        if self.ui.chkAutoOpenFolderGenCode.isChecked():
            Util.openFilePath(voGenPath)

    def onBthUpdateLayaClick(self):
        # 屏蔽按钮可按，防止重复点击
        self.setRunningStatus(True)
        exportTime = datetime.datetime.now()
        tempFolder:str = "svn_" + exportTime.strftime("%Y-%m-%d_%H-%M-%S")
        voBasePath: str = self.getGenLayaVoBasePath()
        voGenPath: str = voBasePath + tempFolder
        if voBasePath is None:
            self.logger.logError("找不到Laya生成代码目录地址！")
            return False
        # 清理临时目录之前的文件
        if self.ui.chkClearDirGen.isChecked():
            self.clearGenFolder(voBasePath)
        # 检出SVN
        if not self.checkOutSvn(voBasePath,
                                tempFolder,
                                self.edata.setting.svnDirLaya):
            return
        # 拷贝代码到目标目录
        if self.ui.chkUpdateCopy.isChecked():
            targetPath: str = self.ui.txtDirLayaFileCopy.text()
            if not os.path.isabs(targetPath):
                targetPath = self.edata.currentPath + targetPath
            if not os.path.isdir(targetPath):
                self.logger.logError("自动拷贝代码目标路径有误：" + targetPath)
            else:
                if self.ui.chkClearDirCopy.isChecked():
                    Util.deleteDirectoryFiles(targetPath, False, CodeLayaGenerator.CodeLayaGenerator.CODE_FILE_EXT_NAME)
                Util.copyDirectoryFiles(voGenPath, targetPath)
                if self.ui.chkAutoOpenFolderGenCode.isChecked():
                    Util.openFilePath(targetPath)

        # 恢复按钮可按
        self.setRunningStatus(False)
        # 打开生成目录
        if self.ui.chkAutoOpenFolderGenCode.isChecked():
            Util.openFilePath(voGenPath)

    def setRunningStatus(self, isRunning: bool):
        if isRunning:
            self.setAllButtonsEnabled(self, False)
        else:
            self.setAllButtonsEnabled(self, True)

    def setAllButtonsEnabled(self, obj: QObject, enabled: bool):
        """递归找到按钮操作Enabled"""
        if obj is None:
            return
        for child in obj.children():
            if type(child) is QPushButton:
                button: QPushButton = child
                # print("找到按钮：" + button.text())
                button.setEnabled(enabled)
            else:
                self.setAllButtonsEnabled(child, enabled)

    def onBthGenJavaClick(self):
        # 屏蔽按钮可按，防止重复点击
        self.setRunningStatus(True)
        # self.syncCheckStateToExcelData()  # 同步勾选状态
        exportTime = datetime.datetime.now()
        exportVersion = uuid.uuid1()
        # 临时目录按时间生成，为了解决SVN占用删除不掉，每次生成都用新目录检出再提交最稳
        tempFolder:str = "svn_" + exportTime.strftime("%Y-%m-%d_%H-%M-%S")

        # 全部执行完打开的目录
        needOpenFolderList:List[str] = []
        # Java
        voBasePath: str = self.getGenJavaVoBasePath()
        voGenPath: str = voBasePath + tempFolder
        if voBasePath is None:
            self.logger.logError("找不到Java生成代码目录地址！")
            return False
        self.update()
        self.repaint()
        # 清理临时目录之前的文件
        if self.ui.chkClearDirGen.isChecked():
            self.clearGenFolder(voBasePath)
        # 创建目录
        Util.tryCreateDirectory(voGenPath)
        # 如果是提交SVN的，需要提前前checkout目录
        if self.ui.chkGenSvn.isChecked():
            if not self.checkOutSvn(voBasePath, tempFolder, self.edata.setting.svnDirJava):
                return

        # 生成代码
        generator: ICodeGenerator = CodeJavaGenerator.CodeJavaGenerator()
        if not generator.loadTemplate:
            self.logger.logError("Java生成模板读取失败！ 任务终止！")
            return
        result = generator.generateCode(voGenPath, str(exportVersion), exportTime)

        if not result:
            self.logger.logError("生成代码失败！请检查配置错误及修复！")
            return False

        # 找出不在excel版本管理下的文件
        exportFiles: List[str] = []
        for excel in self.edata.excelDatas.selectedDatas.values():
            for table in excel.tables.values():
                # 提取类名
                className: str = table.getClassname()
                # 文件名
                filename: str = className + generator.CODE_FILE_EXT_NAME
                exportFiles.append(filename)

        # 找出不在excel版本管理下的文件
        mustDeleteOldFiles: List[str] = []
        for item in os.listdir(voBasePath + tempFolder):
            fn: [str] = os.path.splitext(item)
            filename: str = fn[0]
            ext: str = fn[-1]
            if ext.lower() != generator.CODE_FILE_EXT_NAME:
                continue  # 如果需要判断扩展名但扩展名不对则退出
            if filename.lower() == self.edata.setting.genLibEasyAccessClass.lower():  # ExcelLibDataEasyAccess不处理
                continue
            if filename.lower() == self.edata.setting.genLibConstantClass.lower():  # ExcelLibConstant不处理
                continue
            isOldReamin: bool = True
            for tableNme in exportFiles:
                if tableNme.lower() == item.lower():
                    isOldReamin = False
            if isOldReamin:
                mustDeleteOldFiles.append(item)


        if self.ui.chkDelOld.isChecked():
            self.logger.logNotice("SVN删除已经废弃的类实体")
            # svnUrl: str = self.edata.setting.svnUrl + svnPath
            #newestFullSvnUrl: str = Util.fixUrlBackslash(self.edata.setting.svnDirJava, True)
            # 正式删除过期的文件（含SVN）
            for delfile in mustDeleteOldFiles:
                self.logger.logNotice("SVN删除：" + delfile)
                self.deleteSvnFile(delfile, self.edata.setting.svnDirJava)
                delfilepath = Util.fixPathSlash(voGenPath + "\\" + delfile, False)
                os.chmod(delfilepath, stat.S_IWRITE)  # 文件是只读文件，要删除必须先设置属性
                os.remove(delfilepath)

        self.logger.logAllDone("勾选项目已经全部导出Java代码！(^_−)☆")
        # 加入打开文件夹
        if self.ui.chkAutoOpenFolderGenCode.isChecked():
            needOpenFolderList.append(voGenPath)

        # 提交代码
        if self.ui.chkGenSvn.isChecked():
            self.commitSvn(voGenPath,
                           self.edata.setting.svnDirJava,
                           CodeJavaGenerator.CodeJavaGenerator.CODE_FILE_EXT_NAME)

        # 拷贝代码到目标目录
        if self.ui.chkGenCopy.isChecked():
            targetPath:str = self.ui.txtDirJavaFileCopy.text()
            if not os.path.isabs(targetPath):
                targetPath = self.edata.currentPath + targetPath
            if not os.path.isdir(targetPath):
                self.logger.logError("自动拷贝代码目标路径有误：" + targetPath)
            else:
                self.logger.logNotice("自动拷贝代码到目标目录：" + targetPath)
                if self.ui.chkClearDirCopy.isChecked():
                    Util.deleteDirectoryFiles(targetPath, False,
                                              CodeJavaGenerator.CodeJavaGenerator.CODE_FILE_EXT_NAME)
                Util.copyDirectoryFiles(voGenPath, targetPath)
                if self.ui.chkAutoOpenFolderGenCode.isChecked():
                    needOpenFolderList.append(targetPath)


        # 恢复按钮可按
        self.setRunningStatus(False)
        QMessageBox.information(self, "完成", "已经完成Java类实体代码生成！")

        for folder in needOpenFolderList:
            Util.openFilePath(folder)  # 打开生成目录



    def onBthGenLayaClick(self):
        # 屏蔽按钮可按，防止重复点击
        self.setRunningStatus(True)
        # self.syncCheckStateToExcelData()  # 同步勾选状态
        exportTime = datetime.datetime.now()
        exportVersion = uuid.uuid1()
        # 临时目录按时间生成，为了解决SVN占用删除不掉，每次生成都用新目录检出再提交最稳
        tempFolder:str = "svn_" + exportTime.strftime("%Y-%m-%d_%H-%M-%S")

        # 全部执行完打开的目录
        needOpenFolderList:List[str] = []
        # Laya
        voBasePath: str = self.getGenLayaVoBasePath()
        voGenPath: str = voBasePath + tempFolder
        if voBasePath is None:
            self.logger.logError("找不到Laya生成代码目录地址！")
            return False
        self.update()
        self.repaint()
        # 清理临时目录之前的文件
        if self.ui.chkClearDirGen.isChecked():
            self.clearGenFolder(voBasePath)
        # 创建目录
        Util.tryCreateDirectory(voGenPath)
        # 如果是提交SVN的，需要提前前checkout目录
        if self.ui.chkGenSvn.isChecked():
            if not self.checkOutSvn(voBasePath, tempFolder, self.edata.setting.svnDirLaya):
                return
        # 生成代码
        generator: ICodeGenerator = CodeLayaGenerator.CodeLayaGenerator()
        if not generator.loadTemplate:
            self.logger.logError("Laya生成模板读取失败！ 任务终止！")
            return
        result = generator.generateCode(voGenPath, str(exportVersion), exportTime)

        if not result:
            self.logger.logError("生成代码失败！请检查配置错误及修复！")
            return False

        # 找出不在excel版本管理下的文件
        exportFiles: List[str] = []
        for excel in self.edata.excelDatas.selectedDatas.values():
            for table in excel.tables.values():
                # 提取类名
                className: str = table.getClassname()
                # 文件名
                filename: str = className + generator.CODE_FILE_EXT_NAME
                exportFiles.append(filename)

        # 找出不在excel版本管理下的文件
        mustDeleteOldFiles: List[str] = []
        for item in os.listdir(voBasePath + tempFolder):
            fn: [str] = os.path.splitext(item)
            filename: str = fn[0]
            ext: str = fn[-1]
            if ext.lower() != generator.CODE_FILE_EXT_NAME:
                continue  # 如果需要判断扩展名但扩展名不对则退出
            if filename.lower() == self.edata.setting.genLibEasyAccessClass.lower():  # ExcelLibDataEasyAccess不处理
                continue
            if filename.lower() == self.edata.setting.genLibConstantClass.lower():  # ExcelLibConstant不处理
                continue
            isOldReamin: bool = True
            for tableNme in exportFiles:
                if tableNme.lower() == item.lower():
                    isOldReamin = False
            if isOldReamin:
                mustDeleteOldFiles.append(item)


        if self.ui.chkDelOld.isChecked():
            self.logger.logNotice("SVN删除已经废弃的类实体")
            # svnUrl: str = self.edata.setting.svnUrl + svnPath
            #newestFullSvnUrl: str = Util.fixUrlBackslash(self.edata.setting.svnDirJava, True)
            # 正式删除过期的文件（含SVN）
            for delfile in mustDeleteOldFiles:
                self.logger.logNotice("SVN删除：" + delfile)
                self.deleteSvnFile(delfile, self.edata.setting.svnDirLaya)
                delfilepath = Util.fixPathSlash(voGenPath + "\\" + delfile, False)
                os.chmod(delfilepath, stat.S_IWRITE)  # 文件是只读文件，要删除必须先设置属性
                os.remove(delfilepath)

        self.logger.logAllDone("勾选项目已经全部导出Laya代码！(^_−)☆")


        # 加入打开文件夹
        if self.ui.chkAutoOpenFolderGenCode.isChecked():
            needOpenFolderList.append(voGenPath)
        # 提交代码
        if self.ui.chkGenSvn.isChecked():
            self.commitSvn(voGenPath,
                           self.edata.setting.svnDirLaya,
                           CodeLayaGenerator.CodeLayaGenerator.CODE_FILE_EXT_NAME)

        # 拷贝代码到目标目录
        if self.ui.chkGenCopy.isChecked():
            targetPath:str = self.ui.txtDirLayaFileCopy.text()
            if not os.path.isabs(targetPath):
                targetPath = self.edata.currentPath + targetPath
            if not os.path.isdir(targetPath):
                self.logger.logError("自动拷贝代码目标路径有误：" + targetPath)
            else:
                if self.ui.chkClearDirCopy.isChecked():
                    Util.deleteDirectoryFiles(targetPath, False,
                                              CodeLayaGenerator.CodeLayaGenerator.CODE_FILE_EXT_NAME)
                Util.copyDirectoryFiles(voGenPath, targetPath)
                if self.ui.chkAutoOpenFolderGenCode.isChecked():
                    needOpenFolderList.append(targetPath)

        # 恢复按钮可按
        self.setRunningStatus(False)
        QMessageBox.information(self, "完成", "已经完成Laya类实体代码生成！")

        for folder in needOpenFolderList:
            Util.openFilePath(folder)  # 打开生成目录




    def onBthGenUnityClick(self):
        pass


    def getGenJavaVoBasePath(self):
        """获得java Vo生成基础目录，结尾带'\' """
        dirPath: str = self.getCodePath(self.ui.txtDirJavaFile.text())
        return dirPath

    def getGenLayaVoBasePath(self):
        """获得laya Vo生成基础目录，结尾带'\' """
        dirPath: str = self.getCodePath(self.ui.txtDirLayaFile.text())
        return dirPath

    def getVoBasePath(self, codePath:str):
        dirPath: str = codePath
        if dirPath is None:
            return None
        if not dirPath.endswith("\\"):
            dirPath += "\\"
        dirPath = dirPath.replace("\\\\", "\\")
        dirPath = dirPath.replace(" ", "%20")
        return dirPath

    def deleteSvnFile(self, filename:str, svnDir:str):
        """
        删除svn上的一个文件
        :param filename: 文件名
        :param fileDir: 删除文件对应的本地目录（反推svn地址）
        :return:是否删除成功
        """
        # self.logger.logSpace()  # 空行
        svnUrl: str = Util.fixUrlBackslash(self.edata.setting.svnUrl + "/" + svnDir, True)
        # delfileUrl: str = Util.fixUrlBackslash(svnUrl + "/" + filename, False)
        self.logger.logNotice("开始删除'" + svnUrl + filename + "'SVN文件...")
        SvnTool.svnDelete(self.logger,
                         svnUrl,
                         filename,
                         self.edata.setting.svnUser,
                         self.edata.setting.svnPwd)
